/*
 * Copyright (C) 2001-2010 Jacek Sieka, arnetheduck on gmail point com
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#ifndef DCPLUSPLUS_DCPP_USER_H
#define DCPLUSPLUS_DCPP_USER_H

#include "Util.h"
#include "Pointer.h"
#include "CID.h"
#include "FastAlloc.h"
#include "Flags.h"
#include "forward.h"

class ClientBase;

/** A user connected to one or more hubs. */
class User : public FastAlloc<User>, public intrusive_ptr_base<User>, public Flags
{
	public:
		// [!]IRainman This enum is necessary for a comfortable job status flags
		enum Bits
		{
			ONLINE_BIT,
			PASSIVE_BIT,
			NMDC_BIT,
			BOT_BIT,
			TTH_GET_BIT, //[+]FlylinkDC
			TLS_BIT,
#ifndef IRAINMAN_TEMPORARY_DISABLE_XXX_ICON
			GREY_XXX_5_BIT,
			GREY_XXX_6_BIT,
#endif
			AWAY_BIT, //[+]FlylinkDC
			SERVER_BIT,
			FIREBALL_BIT,
			
			NO_ADC_1_0_PROTOCOL_BIT,
			NO_ADCS_0_10_PROTOCOL_BIT,
			DHT_BIT,
			NAT_TRAVERSAL_BIT,
		};
		
		/** Each flag is set if it's true in at least one hub */
		enum UserFlags
		{
			ONLINE = 1 << ONLINE_BIT,
			PASSIVE = 1 << PASSIVE_BIT,
			NMDC = 1 << NMDC_BIT,
			BOT = 1 << BOT_BIT,
			TTH_GET = 1 << TTH_GET_BIT,     //< User supports getting files by tth -> don't have path in queue...
			TLS = 1 << TLS_BIT,             //< Client supports TLS
#ifndef IRAINMAN_TEMPORARY_DISABLE_XXX_ICON
			GREY_XXX_5 = 1 << GREY_XXX_5_BIT,
			GREY_XXX_6 = 1 << GREY_XXX_6_BIT,
#endif
			AWAY = 1 << AWAY_BIT,
			SERVER = 1 << SERVER_BIT,
			FIREBALL = 1 << FIREBALL_BIT,
			
			NO_ADC_1_0_PROTOCOL = 1 << NO_ADC_1_0_PROTOCOL_BIT,
			NO_ADCS_0_10_PROTOCOL = 1 << NO_ADCS_0_10_PROTOCOL_BIT,
			DHT = 1 << DHT_BIT,
			NAT_TRAVERSAL = 1 << NAT_TRAVERSAL_BIT
		};
#ifdef IRAINMAN_ENABLE_AUTO_BAN
		enum DefinedAutoBanFlags
		{
			BAN_NONE          = 0x0000,
			BAN_BY_MIN_SLOT   = 0x0001,
			BAN_BY_MAX_SLOT   = 0x0002,
			BAN_BY_SHARE      = 0x0004, //-V112
			BAN_BY_LIMIT      = 0x0008
		};
		
		int hasAutoBan(Client *p_Client = NULL);//[+]FlylinkDC
#endif // IRAINMAN_ENABLE_AUTO_BAN
		
		typedef vector<UserPtr> PtrList; // !SMT!-S
		
		struct Hash
		{
			size_t operator()(const UserPtr& x) const
			{
				return ((size_t)(&(*x))) / sizeof(User);
			}
		};
		
		User(const CID& aCID) : cid(aCID),
			m_BytesDownload(0),
			m_BytesUpload(0),
			HubID(0),
			NickID(0),
			CountSlots(0),
			BytesShared(0),
			Limit(0),
			lastDownloadSpeed(0),
			m_support_slots(VIEW_SUPPORT_SLOTS_FIRST)
		{ }
		
		~User() throw() { }
		
		const CID& getCID() const
		{
			return cid;
		}
		operator const CID&() const
		{
			return cid;
		}
		
		GETSET(string, firstNick, FirstNick);
		GETSET(string, lastIP, LastIP);
		//[+]FlylinkDC
		GETSET(uint32_t, HubID, HubID);
		GETSET(uint32_t, NickID, NickID);
		enum SupportSlotsFlag
		{
			VIEW_SUPPORT_SLOTS_FIRST = 0x00,
			VIEW_SUPPORT_SLOTS = 0x01,
			VIEW_NSUPPORT_SLOTS = 0x02
		};
		SupportSlotsFlag m_support_slots;
		//[~]FlylinkDC
		//[+]PPA
		GETSET(int64_t, BytesShared, BytesShared);
		GETSET(int, CountSlots, CountSlots);
		GETSET(int, Limit, Limit);
		GETSET(size_t, lastDownloadSpeed, LastDownloadSpeed);
		//[~]PPA
		
		bool isOnline() const
		{
			return isSet(ONLINE);
		}
		bool isNMDC() const
		{
			return isSet(NMDC);
		}
		
		void AddRatioUpload(int64_t p_size)
		{
			m_BytesUpload += p_size;
		}
		void AddRatioDownload(int64_t p_size)
		{
			m_BytesDownload += p_size;
		}
		void LoadRatio();
		tstring getUDratio() const;
		tstring getUpload() const;
		tstring getDownload() const;
		
		int64_t m_BytesUpload;
		int64_t m_BytesDownload;
	private:
	
		CID cid;
};

#endif // !defined(USER_H)

/**
 * @file
 * $Id: User.h 551 2010-12-18 12:14:16Z bigmuscle $
 */
